#include "pch.h"
#include "menu.h"
#include <common/memory.h>

JOUI::UIMenu::UIMenu()
{
    if (m_hMenu == NULL)
        m_hMenu = CreatePopupMenu();
}

JOUI::UIMenu::~UIMenu()
{
    DestroyMenu(m_hMenu);
}

BOOL JOUI::UIMenu::Append(DWORD dwFlags, UINT_PTR uIDNewItem, LPCWSTR lpwzName, UIImage *hbmpItem)
{
    BOOL nError = 0;
    if (dwFlags == MF_POPUP)
    {
        auto bMenu = (UIMenu*)uIDNewItem;
        if (bMenu)
            uIDNewItem = (UINT_PTR)bMenu->m_hMenu;
    }
    if (AppendMenuW(m_hMenu, dwFlags, uIDNewItem, lpwzName))
    {
        MENUITEMINFOW mii{ 0 };
        mii.cbSize = sizeof(MENUITEMINFOW);
        mii.fMask = MIIM_DATA;
        if (hbmpItem != 0)
            mii.dwItemData = (size_t)hbmpItem;
        nError = SetMenuItemInfoW(m_hMenu, uIDNewItem, FALSE, &mii);
    }
    return nError;
}

BOOL JOUI::UIMenu::EnableItem(UINT uIDNewItem, BOOL wEnable)
{
    return EnableMenuItem(m_hMenu, uIDNewItem, wEnable);
}

BOOL JOUI::UIMenu::Popup(UIWnd* pWnd, DWORD uFlags, INT x, INT y, UIColor crText, UIColor crTextHot, UIColor crBackground, UIColor crShadow, UIColor crBorder, UIColor crItemHot, WinMsgPROC pfnCallback, BOOL IsRadius)
{
    POINT pt;
    GetCursorPos(&pt);
    menu_s menu{ 0 };
    menu.hMenu = m_hMenu;
    menu.uFlags = uFlags;
    menu.x = (x == 0 ? pt.x : x);
    menu.y = (y == 0 ? pt.y : y);
    menu.nReserved = 0;
    menu.lpRC = nullptr;
    menu.pfnCallback = pfnCallback;
    menu.crText = crText;
    menu.crTextHot = crTextHot;
    menu.crItemHot = crItemHot;
    if (crBackground.empty() && pWnd->m_data.crbkg)
        pWnd->m_data.crbkg->GetColor(menu.crBackground);
    else
        menu.crBackground = crBackground;
    menu.IsRadius = IsRadius ? IsRadius : pWnd->m_data.radius;
    if (!crShadow.empty())
        menu.crshadow = crShadow;
    else
    {
        if (pWnd->m_data.crshadow)
            pWnd->m_data.crshadow->GetColor(menu.crshadow);
    }
    if (!crBorder.empty())
        menu.crBorder = crBorder;
    else
    {
        if (pWnd->m_data.crBorder)
            pWnd->m_data.crBorder->GetColor(menu.crBorder);
    }
    pWnd->m_data.lpMenuParams = &menu;
    return TrackPopupMenu(m_hMenu, uFlags, menu.x, menu.y, 0, pWnd->m_data.hWnd, menu.lpRC);
}

BOOL JOUI::UIMenu::Popup(UIWnd* pWnd, HMENU hMenu, INT x, INT y)
{
    menu_s menu{ 0 };
    menu.hMenu = hMenu;
    menu.x = x;
    menu.y = y;
    if (pWnd->m_data.crshadow)
        pWnd->m_data.crshadow->GetColor(menu.crshadow);
    if (pWnd->m_data.crBorder)
        pWnd->m_data.crBorder->GetColor(menu.crBorder);
    if (pWnd->m_data.crbkg)
        pWnd->m_data.crbkg->GetColor(menu.crBackground);
    menu.IsRadius = pWnd->m_data.radius;
    pWnd->m_data.lpMenuParams = &menu;
    return TrackPopupMenu(hMenu, 0, menu.x, menu.y, 0, pWnd->m_data.hWnd, menu.lpRC);
}

BOOL JOUI::UIMenu::End()
{
    return EndMenu();
}

INT JOUI::UIMenu::GetString(UINT uIDNewItem, LPCWSTR& lpNewString)
{
    int nError = 0;
    WCHAR buff[520];
    nError = GetMenuStringW(m_hMenu, uIDNewItem - 1, buff, 520, MF_BYPOSITION);
    lpNewString = StrDupW(buff);
    ExMemFree((LPVOID)buff);
    return nError;
}

BOOL JOUI::UIMenu::SetItem(DWORD dwFlags, UINT uIDNewItem, LPCWSTR lpwzName, UIImage *hbmpItem)
{
    BOOL nError = 0;
    MENUITEMINFOW mii{ 0 };
    mii.cbSize = sizeof(MENUITEMINFOW);
    mii.fMask = MIIM_DATA;
    if (GetMenuItemInfoW(m_hMenu, uIDNewItem, FALSE, &mii))
    {
        if (lpwzName != 0)
        {
            ModifyMenuW(m_hMenu, uIDNewItem, dwFlags, uIDNewItem, lpwzName);

        }

        if (hbmpItem != 0)
        {
            if (mii.dwItemData != 0)
            {
                auto simg = (UIImage*)mii.dwItemData;
                delete simg;
            }
            mii.dwItemData = (size_t)hbmpItem;
        }
        nError = SetMenuItemInfoW(m_hMenu, uIDNewItem, FALSE, &mii);

    }
    return nError;
}

BOOL JOUI::UIMenu::Remove(UINT uIDNewItem)
{
    BOOL nError = 0;
    MENUITEMINFOW mii{ 0 };
    mii.cbSize = sizeof(MENUITEMINFOW);
    mii.fMask = MIIM_DATA | MIIM_FTYPE;
    if (GetMenuItemInfoW(m_hMenu, uIDNewItem, FALSE, &mii))
    {

        if (mii.hbmpItem != 0)
        {
            DeleteObject(mii.hbmpItem);
        }
        nError = DeleteMenu(m_hMenu, uIDNewItem, MF_BYCOMMAND);
    }
    return nError;
}

HMENU JOUI::UIMenu::GetMenu()
{
    return m_hMenu;
}
